#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <ESP32Time.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "BMP.h"
ESP32Time rtc(28800);  //设置时区为UTC+8	
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/27, /* data=*/26);

SemaphoreHandle_t xMutex = NULL;

// 设置要连接的WiFi信息
const char* sta_ssid = "XXXXXX";      
const char* sta_password = "XXXXXX";  

//天气和时间api配置
char* api_key = "Sn9iPiPFRcMuZlq3c";
char* city = "ip";
char* url = "https://api.seniverse.com/v3/weather/now.json?key=";
char* time_url = "http://worldtimeapi.org/api/timezone/Asia/Shanghai";

String timeStr;
String weather;
int temperature;
int unixtime;
String City;
void WifiConnect() {

  WiFi.begin(sta_ssid, sta_password);
  Serial.print("正在连接到WiFi: ");
  Serial.println(sta_ssid);

  // 等待连接到WiFi
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // 连接成功
  Serial.println();
  Serial.println("WiFi已连接");
  Serial.print("STA IP地址: ");
  Serial.println(WiFi.localIP());
}

void setTime() {

  timeStr = rtc.getTime();

}

void Display() {
  setTime();
  char tempStr[18];
  u8g2.clearBuffer();
  u8g2.drawUTF8(5, 15, timeStr.c_str());
  sprintf(tempStr,"%s %s","City:",City.c_str());
  u8g2.drawUTF8(5, 30, tempStr);
  sprintf(tempStr, "%s %d %s","Temp:", temperature,"°C");
  u8g2.drawUTF8(5, 45, tempStr);
  sprintf(tempStr, "%s %s","Weather:", weather.c_str());
  u8g2.drawUTF8(5, 60, tempStr);
  if(rtc.getHour()>18||rtc.getHour()<6){
    u8g2.drawXBMP(85,2,40,40,Sun);
  }
  else{
    u8g2.drawXBMP(85,2,40,40,Moon);
  }
  u8g2.sendBuffer();
}

void getWeather() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;

    // 构建完整的API URL
    char fullUrl[200];
    strcpy(fullUrl, url);
    strcat(fullUrl, api_key);
    strcat(fullUrl, "&location=");
    strcat(fullUrl, city);
    strcat(fullUrl, "&language=zh-Hans&unit=c");

    http.begin(fullUrl);

    // 发送GET请求
    int httpCode = http.GET();
    vTaskDelay(5000);
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      // Serial.println("API响应: " + payload);

      // 解析JSON数据
      DynamicJsonDocument doc(1024);
      deserializeJson(doc, payload);

      // 提取天气信息
      weather = doc["results"][0]["now"]["text"].as<String>();
      temperature = doc["results"][0]["now"]["temperature"].as<int>();
      City = doc["results"][0]["location"]["name"].as<String>();

      // 打印天气信息到串口
      Serial.println("城市: " + City);
      Serial.println("天气: " + weather);
      Serial.println("温度: " + String(temperature) + "°C");
    } else {
      Serial.println("HTTP请求失败 错误码: " + String(httpCode));
    }
    http.end();
  } else {
    Serial.println("WiFi未连接");
  }
  vTaskDelay(5000);
}

void getNowTime() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(time_url);
    http.setTimeout(10000);

    
    int httpCode = 0;
    int i = 0;
    //发起5次GET请求，由于该服务器不稳定所以需要多连几次
    while (httpCode != HTTP_CODE_OK) {
      i++;
      if (i == 5) {
        break;
      }
      httpCode = http.GET();
      vTaskDelay(1000);
    }
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      Serial.println("API响应: " + payload);

      //解析JSON数据，得到unix时间戳
      DynamicJsonDocument doc(1024);
      deserializeJson(doc, payload);
      unixtime = doc["unixtime"].as<int>();
      rtc.setTime(unixtime);

      // 打印时间信息到串口
      Serial.println(unixtime);

    } else {
      Serial.println("HTTP网络时间请求失败 错误码: " + String(httpCode));
    }
    http.end();
  } else {
    Serial.println("WiFi未连接");
  }
  vTaskDelay(10000);
}

void setup() {
  Serial.begin(115200);
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.setFont(u8g2_font_wqy13_t_gb2312);
  u8g2.setDrawColor(1);
  WifiConnect();
  rtc.setTime(1736784000);  //默认设置时间为00:00:00

  xMutex = xSemaphoreCreateMutex();
  xTaskCreatePinnedToCore(task1, "task1", 10240, NULL, 1, NULL, 1);  //创建任务1
  xTaskCreatePinnedToCore(task2, "task2", 4096, NULL, 1, NULL, 1);   //创建任务2
  xTaskCreatePinnedToCore(task3, "task3", 4096, NULL, 1, NULL, 1);   //创建任务3
}


void loop() {

  //这里啥也不用写
}


void task1(void* pvParameters) {
  while (1) {

    Display();
    vTaskDelay(1);
  }
}

//两个网络服务需要使用互斥锁
void task2(void* pvParameters) {
  while (1) {
    if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
      getWeather();
      xSemaphoreGive(xMutex);
    }
    vTaskDelay(1);
  }
}

void task3(void* pvParameters) {
  while (1) {
    if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
      getNowTime();
      xSemaphoreGive(xMutex);
    }
    vTaskDelay(1);
  }
}
